home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_2 / chasm01.sha / lex.c < prev    next >
C/C++ Source or Header  |  1995-03-23  |  5KB  |  397 lines

  1. /*
  2.  *    lex.c - lexical analyzer
  3.  *
  4.  *    @(#)lex.c    1.1 91/04/10
  5.  *
  6.  *    Copyright (c) 1991 Steve Scherf
  7.  *
  8.  *    Author:    Steve Scherf
  9.  *    Date:    Wed Apr 10 22:53:11 PDT 1991
  10.  *
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <ctype.h>
  15. #include "chasm.h"
  16.  
  17. extern int yylval;
  18.  
  19. char *insttab[] = {
  20.     "add", "and", "bcd", "cld", "data", "def", "dmp", "dsp", "ink",
  21.     "jmp", "jof", "jsr", "mem", "mov", "or", "res", "ret", "rnd",
  22.     "sar", "seq", "shl", "shr", "sip", "sne", "snp", "ssc", "sub", "xor"
  23. };
  24.  
  25. int ninst = sizeof(insttab) / sizeof(char *);
  26.  
  27. char *vartab[] = {
  28.     "dtimer",
  29.     "stimer",
  30.     "i"
  31. };
  32.  
  33. int nvar = sizeof(vartab) / sizeof(char *);
  34.  
  35.  
  36. char getch();
  37. char getcconst();
  38. char getslash();
  39. char getslashval();
  40. char getqchar();
  41. char *gettoken();
  42. int getinstr();
  43. int getstr();
  44. int getconst();
  45. int getreg();
  46. int gethex();
  47. int getoct();
  48. int getdec();
  49. int getvar();
  50.  
  51.  
  52. /* lexical analyzer */
  53. yylex()
  54. {
  55.     unsigned int x;
  56.     register int i;
  57.     register char *s;
  58.     char l[512], lbl[512], c;
  59.  
  60.     s = gettoken();
  61.  
  62.     if(!s)
  63.         return 0;
  64.     
  65.     if(*s == '"')
  66.         if((yylval = (int)getstr()) != 0)
  67.             return STRING;
  68.         else
  69.             return 1;
  70.  
  71.     if(*s == '\'')
  72.         if((yylval = getcconst()) != -1)
  73.             return CONST;
  74.         else
  75.             return 1;
  76.  
  77.     if(isctok(*s))
  78.         return *s;
  79.  
  80.     if((i = getinstr(s)) >= 0)
  81.         return(i + IBASE);
  82.  
  83.     if((yylval = getvar(s)) != -1)
  84.         return VAR;
  85.  
  86.     if((yylval = getreg(s)) != -1)
  87.         return REG;
  88.  
  89.     if((yylval = getconst(s)) != -1)
  90.         return CONST;
  91.  
  92.     if(islabel(s) != 0) {
  93.         strcpy(lbl, s);
  94.         yylval = (int)lbl;
  95.         return LABEL;
  96.     }
  97.  
  98.     return 1;
  99. }
  100.  
  101.  
  102. /* read one token from input */
  103. char *
  104. gettoken()
  105. {
  106.     register char *p;
  107.     static char l[512];
  108.     static char ctok = 0;
  109.  
  110.     if(ctok) {
  111.         l[0] = ctok;
  112.         l[1] = '\0';
  113.         ctok = 0;
  114.         return l;
  115.     }
  116.  
  117.     p = l;
  118.     while((*p = getch()) != EOF && isspace(*p) && !isctok(*p))
  119.         continue;
  120.  
  121.     if(*p == EOF)
  122.         return 0;
  123.  
  124.     if(isctok(*p)) {
  125.         *(++p) = '\0';
  126.         return l;
  127.     }
  128.  
  129.     p++;
  130.     while((*p = getch()) != EOF && !isspace(*p) && *p != ',' && *p != ':' &&
  131.         p < l + sizeof(l) - 1)
  132.         p++;
  133.     if(isctok(*p))
  134.         ctok = *p;
  135.     *p = '\0';
  136.  
  137.     return l;
  138. }
  139.  
  140.  
  141. /* get one character, ignoring comments */
  142. char
  143. getch()
  144. {
  145.     register char c;
  146.  
  147.     if((c = getc(ifp)) != ';' && c != '/')
  148.         return c;
  149.  
  150.     while(getc(ifp) != '\n')
  151.         continue;
  152.     return '\n';
  153. }
  154.  
  155.  
  156. /* return true if c is a one character token */
  157. isctok(c)
  158. register c;
  159. {
  160.     if(c == ',' || c == '\n' || c == '"' || c == '\'' || c == ':')
  161.         return 1;
  162.  
  163.     return 0;
  164. }
  165.  
  166.  
  167. /* get a single-quoted character constant from input */
  168. char
  169. getcconst()
  170. {
  171.     char c, d;
  172.  
  173.     c = getc(ifp);
  174.     if(c == '\\') {
  175.         if((c = getslash()) == EOF)
  176.             return -1;
  177.     }
  178.     else
  179.         if(c == '\n') {
  180.             ungetc(c, ifp);
  181.             return -1;
  182.         }
  183.  
  184.     if((d = getc(ifp)) == '\n')
  185.         ungetc(d, ifp);
  186.     else
  187.         if(d == '\'')
  188.             return c;
  189.  
  190.     return -1;
  191. }
  192.  
  193.  
  194. /* get string of characters from input */
  195. int
  196. getstr()
  197. {
  198.     register char *p;
  199.     static char l[512];
  200.  
  201.     p = l;
  202.     while((*p = getc(ifp)) != EOF && *p != '\n' && *p != '"' &&
  203.         p < l + sizeof(l) - 1) {
  204.         if(*p == '\\' && (*p = getslash()) == EOF)
  205.             return 0;
  206.         p++;
  207.     }
  208.  
  209.     if(*p == '\n')
  210.         ungetc('\n', ifp);
  211.  
  212.     if(*p != '"')
  213.         return 0;
  214.  
  215.     *p = '\0';
  216.  
  217.     return((int)l);
  218. }
  219.  
  220.  
  221. /* get a backslash-escaped character from input */
  222. char
  223. getslash()
  224. {
  225.     register char c;
  226.  
  227.     if((c = getc(ifp)) == '\n') {
  228.         ungetc(c, ifp);
  229.         return EOF;
  230.     }
  231.  
  232.     switch(c) {
  233.         case 'b':
  234.             return '\b';
  235.         case 'n':
  236.             return '\n';
  237.         case 'r':
  238.             return '\r';
  239.         case 't':
  240.             return '\t';
  241.         case '0':
  242.             return '\0';
  243.         case EOF:
  244.             return EOF;
  245.         default:
  246.             return c;
  247.     }
  248. }
  249.  
  250.  
  251. /* return true if s is an alphanumeric label */
  252. islabel(s)
  253. char *s;
  254. {
  255.     if(isdigit(*s))
  256.         return 0;
  257.  
  258.     while(*s && (isalnum(*s) || *s == '_'))
  259.         s++;
  260.  
  261.     return(*s == '\0');
  262. }
  263.  
  264.  
  265. /* if s is an instruction, return index in table */
  266. int
  267. getinstr(s)
  268. char *s;
  269. {
  270.     register char *p1, *p2;
  271.     register int i;
  272.  
  273.     for(i = 0; i < ninst; i++) {
  274.         for(p1 = s, p2 = insttab[i]; *p1 && *p2; p1++, p2++)
  275.             if(*p1 != *p2 && *p1 != toupper(*p2))
  276.                 break;
  277.  
  278.         if(!*p1 && !*p2)
  279.             return i;
  280.     }
  281.  
  282.     return -1;
  283. }
  284.  
  285.  
  286. /* if s is a register, return its number */
  287. int
  288. getreg(s)
  289. register char *s;
  290. {
  291.     register int x;
  292.  
  293.     if((s[0] == 'V' || s[0] == 'v') && s[2] == '\0') {
  294.         x = gethex(s+1);
  295.         if(x >= 0x0 && x <= 0xF)
  296.             return x;
  297.     }
  298.  
  299.     return -1;
  300. }
  301.  
  302.  
  303. /* convert s to an integer of the appropriate base */
  304. int
  305. getconst(s)
  306. register char *s;
  307. {
  308.     if(s[0] == '0')
  309.         if(s[1] == 'x' || s[1] == 'X')
  310.             return(gethex(s+2));
  311.         else
  312.             return(getoct(s+1));
  313.  
  314.     return(getdec(s));
  315. }
  316.  
  317.  
  318. /* convert s to a hex integer */
  319. int
  320. gethex(s)
  321. register char *s;
  322. {
  323.     register int n, l;
  324.  
  325.     for(n = 0; *s; s++) {
  326.         if(!isxdigit(*s))
  327.             return -1;
  328.  
  329.         if(isdigit(*s))
  330.             n = (n << 4) + *s - '0';
  331.         else {
  332.             if(isupper(*s))
  333.                 *s = tolower(*s);
  334.             n = (n << 4) + *s - 'a' + 10;
  335.         }
  336.     }
  337.  
  338.     return n;
  339. }
  340.  
  341.  
  342. /* convert s to an octal integer */
  343. int
  344. getoct(s)
  345. register char *s;
  346. {
  347.     register int n;
  348.  
  349.     for(n = 0; *s; s++) {
  350.         if(!isdigit(*s) || *s > '7')
  351.             return -1;
  352.  
  353.         n = (n << 3) + *s - '0';
  354.     }
  355.  
  356.     return n;
  357. }
  358.  
  359.  
  360. /* convert s to a decimal integer */
  361. int
  362. getdec(s)
  363. register char *s;
  364. {
  365.     register int n;
  366.  
  367.     for(n = 0; *s; s++) {
  368.         if(!isdigit(*s))
  369.             return -1;
  370.  
  371.         n = (n * 10) + *s - '0';
  372.     }
  373.  
  374.     return n;
  375. }
  376.  
  377.  
  378. /* if s is a special variable, return its index */
  379. int
  380. getvar(s)
  381. char *s;
  382. {
  383.     register char *p1, *p2;
  384.     register int i;
  385.  
  386.     for(i = 0; i < nvar; i++) {
  387.         for(p1 = s, p2 = vartab[i]; *p1 && *p2; p1++, p2++)
  388.             if(*p1 != *p2 && *p1 != toupper(*p2))
  389.                 break;
  390.  
  391.         if(!*p1 && !*p2)
  392.             return i;
  393.     }
  394.  
  395.     return -1;
  396. }
  397.